<template>
  <div class="low-code-form pd-tb-10-px">
    <el-form :model="formData"
             :inline="inline"
             ref="form"
             class="low-code-form"
             size="small"
             :label-position="labelPosition"
    >
      <el-row :gutter="10">
        <template  v-for="(field) in fields" >
          <el-col :span="setSpan(field)" v-if="handlerShow(field)">
            <el-form-item
                :label="field.title"
                :prop="field.key"
                :class="field.class"
                :rules="getRules(field)"
                :required="isRequired(field)"
                :label-width="nvl(field.labelWidth, '100px')">
              <component :is="getComponent(field)"
                         v-if="!field.slot"
                         v-model="formData[field.key]"
                         style="width:100%"
                         v-bind="getAttrs(field)"
                         v-on="field.on"
                         :disabled="isDisabled(field)"
              >
              </component>
              <slot  v-else  :name="field.slot" :field="field" :value="formData[field.key]"></slot>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
      <el-form-item style="margin: 0">
        <slot name="footer-button"></slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import util from "utils/util";
import commons from "utils/commons";

export default {
  name: "BaseForm" ,
  props:{
    formData: {
      type: Object ,
      default(){
        return {}
      }
    },
    fields:{
      type: Array ,
      required:true
    },
    span: {
      type: Number ,
      default: 6
    },
    size: 'small',
    inline: {
      type: Boolean,
      default: false
    },
    labelPosition:{
      type: String,
      default:  "right"
    },
  },
  data(){
    return {
      register:{
        input: 'el-input',
        select: 'v2-select',
        switch: 'el-switch',
        number: 'el-input-number'
      },
      spanFull: 24 ,
    }
  },
  created(){

  },
  watch:{
  },
  computed:{

  },
  methods:{
    resetFields(){

    },
    handlerShow(field){
      if(util.isVoid(field.show)){
        return true
      }
      if(util.isFun(field.show)){
        return field.show(this.formData)
      }
      return field.show === true
    },
    submit(){
      this.$refs.form.validate((status)=>{
        if(status){
          this.$emit("submit",this.formData)
        }else{
          this.$message.error("请填写必填项")
        }
      })

    },
    validate(callback){
      this.$refs.form.validate((status)=>{
        callback && callback(status)
      })
    },
    setSpan(item){
      if(this.inline){
        return this.nvl(item.span , this.span)
      }
      return this.spanFull
    },
    setValue(source , target){
      for(let key in source){
        this.$set(target , key , source[key])
      }
    },
    getRules(field) {
      let isRequired =  false
      if(util.isFun(field.required)){
        isRequired = field.required
      }else if(!util.isVoid(field.required)){
        isRequired = field.required
      }
      return [{
        required: isRequired,
        message: `${field.title}必填`,
      }];
    },
    isRequired(field) {
      let isRequired =  false
      if(util.isFun(field.required)){
        isRequired = field.required
      }else if(!util.isVoid(field.required)){
        isRequired = field.required
      }
      return isRequired
    },
    nvl(a,b){
      return [undefined,null,''].includes(a) ? b :a
    },
    getComponent(field){
      if(!field.is){
        return this.register.input
      }
      let comp = this.register[field.is] ;
      comp = this.nvl(comp,field.is)
      return comp
    },
    getAttrs(field){
      let attrs = field.attrs || {} ;
      return Object.assign({size: this.size},attrs)
    },
    isDisabled(field) {
      if(util.isFun(field.disabled)){
        return  field.disabled(field)
      }else if(util.isBool(field.disabled)){
        return field.disabled
      }
      return false;
    },
  }
}
</script>

<style >
.low-code-form>.el-form--inline .el-form-item{
  display: flex !important;
  width: 100%;
}
.low-code-form>.el-form--inline .el-form-item>.el-form-item__content{
  display: flex ;
  flex: 1 !important;
}
</style>



